package com.zscat.mallplus.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itextpdf.text.pdf.codec.Base64;
import com.zscat.mallplus.annotation.IgnoreAuth;
import com.zscat.mallplus.dms.service.IQsgMemberStoreService;
import com.zscat.mallplus.dms.service.IQsgStoreService;
import com.zscat.mallplus.dms.service.impl.QsgMemberStoreServiceImpl;
import com.zscat.mallplus.exception.BusinessMallException;
import com.zscat.mallplus.qsg.QsgMemberStore;
import com.zscat.mallplus.qsg.QsgRoom;
import com.zscat.mallplus.qsg.QsgStore;
import com.zscat.mallplus.single.ApiBaseAction;
import com.zscat.mallplus.sys.mapper.SysAppletSetMapper;
import com.zscat.mallplus.ums.entity.SysAppletSet;
import com.zscat.mallplus.ums.entity.UmsMember;
import com.zscat.mallplus.ums.mapper.UmsMemberMapper;
import com.zscat.mallplus.ums.service.IUmsAdminMemberService;
import com.zscat.mallplus.ums.service.IUmsMemberService;
import com.zscat.mallplus.utils.*;
import com.zscat.mallplus.vo.ApiContext;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 会员登录注册管理Controller
 * https://github.com/shenzhuan/mallplus on 2018/8/3.
 */
@Controller
@Api(tags = "UmsMemberController", description = "会员管理系统")
@RequestMapping("/api/member")
@Slf4j
public class UmsMemberController extends ApiBaseAction {
    private static Logger logger = LoggerFactory.getLogger(UmsMemberController.class);

    @Autowired
    private IUmsMemberService memberService;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Resource
    private SysAppletSetMapper appletSetMapper;
    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private ApiContext apiContext;

    @Resource
    private UmsMemberMapper memberMapper;

    @Autowired
    private IUmsAdminMemberService adminMemberService;

    @Autowired
    private IQsgStoreService storeService;

    @Autowired
    private IQsgMemberStoreService memberStoreService;

    @IgnoreAuth
    @ApiOperation(value = "微信网页授权登录")
    @GetMapping(value = "/weixinLogin")
    @ResponseBody
    public Object weixinLogin(HttpServletRequest request, String code) {
        logger.info("执行微信登录:{}", code);
        try {
            Map<String, Object> result = adminMemberService.loginByWeixinPage(code);
            logger.info("微信登录授权结果:{}", JSON.toJSONString(result));
            return new CommonResult().success(result);
        } catch (BusinessMallException e) {
            e.printStackTrace();
            return new CommonResult().failed("微信网页授权失败");
        }
    }

    @ApiOperation("更新会员的手机号")
    @RequestMapping(value = "/updateMemberPhone", method = RequestMethod.POST)
    @ResponseBody
    public Object updateMemberPhone(@RequestParam String phone) {
        UmsMember umsMember = UserUtils.getCurrentMember();
        umsMember.setPhone(phone);
        memberService.updateById(umsMember);
        return new CommonResult().success("更新会员手机成功.");
    }

    @ApiOperation("添加会员")
    @RequestMapping(value = "/createMember", method = RequestMethod.POST)
    @ResponseBody
    public Object createMember(@RequestBody QsgMemberStore memberStore) {
        UmsMember member = memberService.getById(memberStore.getMemberId());
        QsgStore store = storeService.getById(memberStore.getStoreId());
        QsgMemberStore ms = new QsgMemberStore();
        ms.setPhone(member.getPhone());
        ms.setCreateDatetime(new Date());
        ms.setMemberId(member.getId());
        ms.setStoreId(memberStore.getStoreId());
        ms.setStoreName(store.getName());
        memberStoreService.save(ms);
        return new CommonResult().success("添加会员成功.");
    }

    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/token/refresh", method = RequestMethod.GET)
    @ResponseBody
    public Object refreshToken(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = memberService.refreshToken(token);
        if (refreshToken == null) {
            return new CommonResult().failed();
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return new CommonResult().success(tokenMap);
    }


    @ApiOperation(value = "登出功能")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ResponseBody
    public Object logout() {
        return new CommonResult().success(null);
    }

    @ResponseBody
    @RequestMapping("login/{authCode}")
    public Object login(@PathVariable String authCode) throws Exception {
        // 1. 服务端获取access_token、user_id
        AlipaySystemOauthTokenResponse response = getAccessToken(authCode);
        if (response.isSuccess()) {
            log.info("获取access_token - 调用成功");
            /**
             *  获取到用户信息后保存到数据
             *  1. 如果数据库不存在对用的 alipayUserId, 则注册
             *  2. 如果存在，则获取数据库中的信息再返回
             */
            String accessToken = response.getAccessToken();
            String alipayUserId = response.getUserId();
            log.info("accessToken:" + accessToken);
            log.info("alipayUserId:" + alipayUserId);
        } else {
            System.out.println("获取access_token - 调用失败");
        }
        return "";
    }

    // 服务端获取access_token、user_id
    private AlipaySystemOauthTokenResponse getAccessToken(String authCode) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                "2021001104632593",                    // 1. 填入appid
                "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCGTMxda2+ozFRcKAT1goB1hSzqTBTNwGeqyLdFT4gykHIpLncG74qw403zHEsbqqI7Fjw4b4aQqm7ufJmmZERVjTX1/UF0x3haXwdrD3FQF52J2fnRLoWW0gHqMmIu2bWiFsY9i0SRiYvf5GEO3CrrlONw73PKqfwYNvHJd+hnt/Ej/6skws9KfFAQ+uEK8QEVkQ9CcGpic4UG4rV6jALkMcpSsZGt3Qkn6lNPhrCXLuK9xy7m5Cb4facI+atAyCG+EyVrWUk+h+YAvgcFGvhfW/RkQ754HY+GpABnNnyNYOeLN25bbfp+ltJOt+MKYlGpGIONfd9EXAJx6tbhvubnAgMBAAECggEAKMPlALJc2Vr0fGi1YKR1Q7bh9FiVtAKkNQXqA4Lpr5eC35c4EAXkDl9gyNucvNAloFPWgbbwnLbvJzrxFL24tFNBvuJZ3Q2zLZNM2CV+2rXgXvioSOObLzWd2S3j+Z6h8IqDMCk27gpXR+W1xGH2MT4nb59vgWPpnpwG9oWMKPcMI7AKuzlYRzK+Rdz7HullIS0up8GtJjXiVPnF7nd3KSwRLYCQnWbRjvEjwMQqD1rY9X+aQdsB/PzyhglcA4L7HGdx9NC6gS1FRYjYQY2ghi6mVYZthLy3W+TR5sZrbhInokknEju0URMY2sxuOu0UK9NJaK8tWQXRo2zx7/AhgQKBgQDoq5SlueJ/t8z6XqC/VIeDmRScCmW5eMIWZedzK/7AWiB3Z9rjE3chMM1C0i7WxLJLRZ/pOOEpF40nyEAbAjcYFJcQRUAWm9ct13vFPac2UWULsHRBTfZLc2nY0gEMA3sQECpwqpH0MXy7HLZLfStPV2UF88x8W2E0OFcd8P0AJwKBgQCTxCYdr0k5XgMunnqz9J0K0UZj5JVATI0YrfpIPH3fok9FIKI6I/XiIDu/Z3rlHUgYeaBH9ukJibPNDt9YgtX7JBrT/ZDL+BP4lcsONWEfeNM+Jje2kgpjEXzRYTBQrpRSRQEbwqj0Nd5KPApNyGUNc7Hab8WDSRhRdVHQ/mxbQQKBgQC2FyJcmR+0SMp433n6g1MTIMjKXjDCeMmc8d+zeSkErQRfrr3VnTRMm37o3smdd4757eF6ivNcT3w/OC9Dc/ZeOC8JosjHaOt8ivnooZmtnwHvpgc13Kf24Lpj3+bF2iuDpMMyLavQarJtVcktRyaQD5uWjvjoEjP+xGEZo7K9XQKBgACwDAFdXHjg4CDqaeXGgKiZOruiR7OJ56oyvRRy+5770WSf90FQA4fu4HhOkfrY/QnoHv/WvVTnCCgvJojx6u8FRv6vkmnwmJ8yi0RgqTgNRuZmJSI7YcL+RNdwnVnyxgvv+EZZzJF+Yq9zwhSElzvNywkaNhAbWfqfEidn17dBAoGAbWwDgrLLrM/EemOR2bCAw+hkFeASQHqDqLYGty31mefIzlP2hThEDAoioo1IcaMgtmlegYlh4ma9dB20whnxO4JwLZ0lyveno6dHZWN54gjz/GfEPbPfHRa8z9+eSXJNP9Tea2GHz6J+cd2ou0IrJpXFO6RA/s/tbkb2dAGfTQM=",            // 2. 填入私钥
                "json",
                "utf-8",
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA46nUIHDiQXgn2GflQcQFjDygT6JOn/S5JtJ0tjVQ95tty+biOsX5XZqJBcp+5LntA5EfP5ggguIMnrMnJuoyXKYSrFtJmk2Miazgt71aB94mrnxMaS/49mR9aQDP8J+uko4ERM4vIGGZDahzDKX9q3LC9nRZqCrG7W8/hYcFK433MSW7F+dAVf5eIaGtzBqb7FYqZmqyUV1ueTkOuu3hVvNDxTQexgr0eoTLHplFF2JhiyYyTf6sl4cOToKLAIFekSPu/ETuwOPG39rWcJYfnbfRlGGyUctClgyE6NdB0bEm8vz2IUXuY/HPeq3ilndJU85PtzsJOne/T0Mg3Rqf9QIDAQAB",         // 3. 填入公钥
                "RSA2");
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(authCode);        // 4. 填入前端传入的授权码authCode
        request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");    // 0. 不用管
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);

        return response;
    }

    @ResponseBody
    @RequestMapping("/getopenid")
    public CommonResult getUserInfo(@RequestParam(name = "code") String code) throws Exception {
        SysAppletSet sysAppletSet = appletSetMapper.selectOne(new QueryWrapper<>());
        System.out.println("code" + code);
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        url += "?appid=" + sysAppletSet.getAppid();//自己的appid
        url += "&secret=" + sysAppletSet.getAppsecret();//自己的appSecret
        url += "&js_code=" + code;
        url += "&grant_type=authorization_code";
        url += "&connect_redirect=1";
        String res = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // DefaultHttpClient();
        HttpGet httpget = new HttpGet(url);    //GET方式
        CloseableHttpResponse response = null;
        // 配置信息
        RequestConfig requestConfig = RequestConfig.custom()          // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(5000)                    // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(5000)             // socket读写超时时间(单位毫秒)
                .setSocketTimeout(5000)                    // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(false).build();           // 将上面的配置信息 运用到这个Get请求里
        httpget.setConfig(requestConfig);                         // 由客户端执行(发送)Get请求
        response = httpClient.execute(httpget);                   // 从响应模型中获取响应实体
        HttpEntity responseEntity = response.getEntity();
        System.out.println("响应状态为:" + response.getStatusLine());
        if (responseEntity != null) {
            res = EntityUtils.toString(responseEntity);
            System.out.println("响应内容长度为:" + responseEntity.getContentLength());
            System.out.println("响应内容为:" + res);
        }
        // 释放资源
        if (httpClient != null) {
            httpClient.close();
        }
        if (response != null) {
            response.close();
        }
        JSONObject jo = JSON.parseObject(res);
        return new CommonResult().success(jo);
    }

    private UmsMember queryByOpenId(String openId) {
        UmsMember member = new UmsMember();
        member.setWeixinOpenid(openId);
        QueryWrapper qw = new QueryWrapper();
        qw.orderByDesc("id");
        qw.setEntity(member);
        List<UmsMember> members = memberMapper.selectList(qw);
        if (null != members && !members.isEmpty()) {
            return members.get(0);
        }
        return null;
    }

    @RequestMapping(value = "deciphering", method = RequestMethod.GET)
    public @ResponseBody
    Object deciphering(String encrypdata,
                       String ivdata, String sessionkey,
                       HttpServletRequest request,
                       String openid) {

        byte[] encrypData = Base64.decode(encrypdata);
        byte[] ivData = Base64.decode(ivdata);
        byte[] sessionKey = Base64.decode(sessionkey);
        String str = "";
        try {
            str = decrypt(sessionKey, ivData, encrypData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        UmsMember userVo = this.queryByOpenId(openid);
        Map<String, Object> resultObj = new HashMap<String, Object>();
        JSONObject jsonObject = JSONObject.parseObject(str);
        String phone = jsonObject.getString("phoneNumber");
        String appid = jsonObject.getJSONObject("watermark").getString("appid");
        String token = null;
        if (null == userVo) {
            UmsMember umsMember = new UmsMember();
            umsMember.setUsername("wxapplet" + CharUtil.getRandomString(12));
            umsMember.setSourceType(2);
            umsMember.setCreateTime(new Date());
            umsMember.setStatus(1);
            umsMember.setBlance(new BigDecimal(10000));
            umsMember.setIntegration(0);
            umsMember.setPhone(phone);
            umsMember.setMemberLevelId(4L);
            umsMember.setWeixinOpenid(openid);
            umsMember.setIcon("/upload/img/avatar/01.jpg");
            umsMember.setNickname("微信用户");
            memberMapper.insert(umsMember);
            token = jwtTokenUtil.generateToken(umsMember.getUsername());
            resultObj.put("userId", umsMember.getId());
            resultObj.put("userInfo", umsMember);
        } else {
            userVo.setPhone(phone);
            memberMapper.updateById(userVo);
            token = jwtTokenUtil.generateToken(userVo.getUsername());
            resultObj.put("userId", userVo.getId());
            resultObj.put("userInfo", userVo);
        }
        resultObj.put("tokenHead", tokenHead);
        resultObj.put("token", token);
        resultObj.put("sessionKey",sessionKey);
        resultObj.put("appId",appid);
        return ApiBaseAction.toResponsSuccess(resultObj);

    }

    public static String decrypt(byte[] key, byte[] iv, byte[] encData) throws Exception {
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        //解析解密后的字符串
        return new String(cipher.doFinal(encData), "UTF-8");
    }


    // 获取支付宝用户信息
    private AlipayUserInfoShareResponse getAliUserInfo(String accessToken) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                "2021001104632593",                    // 1. 填入appid
                "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCGTMxda2+ozFRcKAT1goB1hSzqTBTNwGeqyLdFT4gykHIpLncG74qw403zHEsbqqI7Fjw4b4aQqm7ufJmmZERVjTX1/UF0x3haXwdrD3FQF52J2fnRLoWW0gHqMmIu2bWiFsY9i0SRiYvf5GEO3CrrlONw73PKqfwYNvHJd+hnt/Ej/6skws9KfFAQ+uEK8QEVkQ9CcGpic4UG4rV6jALkMcpSsZGt3Qkn6lNPhrCXLuK9xy7m5Cb4facI+atAyCG+EyVrWUk+h+YAvgcFGvhfW/RkQ754HY+GpABnNnyNYOeLN25bbfp+ltJOt+MKYlGpGIONfd9EXAJx6tbhvubnAgMBAAECggEAKMPlALJc2Vr0fGi1YKR1Q7bh9FiVtAKkNQXqA4Lpr5eC35c4EAXkDl9gyNucvNAloFPWgbbwnLbvJzrxFL24tFNBvuJZ3Q2zLZNM2CV+2rXgXvioSOObLzWd2S3j+Z6h8IqDMCk27gpXR+W1xGH2MT4nb59vgWPpnpwG9oWMKPcMI7AKuzlYRzK+Rdz7HullIS0up8GtJjXiVPnF7nd3KSwRLYCQnWbRjvEjwMQqD1rY9X+aQdsB/PzyhglcA4L7HGdx9NC6gS1FRYjYQY2ghi6mVYZthLy3W+TR5sZrbhInokknEju0URMY2sxuOu0UK9NJaK8tWQXRo2zx7/AhgQKBgQDoq5SlueJ/t8z6XqC/VIeDmRScCmW5eMIWZedzK/7AWiB3Z9rjE3chMM1C0i7WxLJLRZ/pOOEpF40nyEAbAjcYFJcQRUAWm9ct13vFPac2UWULsHRBTfZLc2nY0gEMA3sQECpwqpH0MXy7HLZLfStPV2UF88x8W2E0OFcd8P0AJwKBgQCTxCYdr0k5XgMunnqz9J0K0UZj5JVATI0YrfpIPH3fok9FIKI6I/XiIDu/Z3rlHUgYeaBH9ukJibPNDt9YgtX7JBrT/ZDL+BP4lcsONWEfeNM+Jje2kgpjEXzRYTBQrpRSRQEbwqj0Nd5KPApNyGUNc7Hab8WDSRhRdVHQ/mxbQQKBgQC2FyJcmR+0SMp433n6g1MTIMjKXjDCeMmc8d+zeSkErQRfrr3VnTRMm37o3smdd4757eF6ivNcT3w/OC9Dc/ZeOC8JosjHaOt8ivnooZmtnwHvpgc13Kf24Lpj3+bF2iuDpMMyLavQarJtVcktRyaQD5uWjvjoEjP+xGEZo7K9XQKBgACwDAFdXHjg4CDqaeXGgKiZOruiR7OJ56oyvRRy+5770WSf90FQA4fu4HhOkfrY/QnoHv/WvVTnCCgvJojx6u8FRv6vkmnwmJ8yi0RgqTgNRuZmJSI7YcL+RNdwnVnyxgvv+EZZzJF+Yq9zwhSElzvNywkaNhAbWfqfEidn17dBAoGAbWwDgrLLrM/EemOR2bCAw+hkFeASQHqDqLYGty31mefIzlP2hThEDAoioo1IcaMgtmlegYlh4ma9dB20whnxO4JwLZ0lyveno6dHZWN54gjz/GfEPbPfHRa8z9+eSXJNP9Tea2GHz6J+cd2ou0IrJpXFO6RA/s/tbkb2dAGfTQM=",            // 2. 填入私钥
                "json",
                "utf-8",
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA46nUIHDiQXgn2GflQcQFjDygT6JOn/S5JtJ0tjVQ95tty+biOsX5XZqJBcp+5LntA5EfP5ggguIMnrMnJuoyXKYSrFtJmk2Miazgt71aB94mrnxMaS/49mR9aQDP8J+uko4ERM4vIGGZDahzDKX9q3LC9nRZqCrG7W8/hYcFK433MSW7F+dAVf5eIaGtzBqb7FYqZmqyUV1ueTkOuu3hVvNDxTQexgr0eoTLHplFF2JhiyYyTf6sl4cOToKLAIFekSPu/ETuwOPG39rWcJYfnbfRlGGyUctClgyE6NdB0bEm8vz2IUXuY/HPeq3ilndJU85PtzsJOne/T0Mg3Rqf9QIDAQAB",         // 3. 填入公钥
                "RSA2");
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = alipayClient.execute(request, accessToken);
        if (response.isSuccess()) {
            log.info("获取会员信息 - 调用成功");
            return response;
        }
        return null;
    }

    @ApiOperation("更新会员的昵称")
    @RequestMapping(value = "/updateMemberNick", method = RequestMethod.POST)
    @ResponseBody
    public Object updateMemberNick(@RequestParam Long memberId, @RequestParam String nickname) {
        UmsMember umsMember = memberService.getById(memberId);
        umsMember.setNickname(nickname);
        memberService.updateById(umsMember);
        return new CommonResult().success("更新会员昵称成功.");
    }

    @ResponseBody
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public Object upload(MultipartFile file, Long memberId, Long storeid) {
        try {
            String imageUrl = OssUtil.upload(file, OssUtil.FileDirType.ARTICLE_IMAGES);
            UmsMember member = memberService.getById(memberId);
            member.setIcon(imageUrl);
//            member.setAvatar(imageUrl);
            memberService.updateById(member);
            return new CommonResult().success(imageUrl);
        } catch (Exception be) {
            return new CommonResult().failed();
        }
    }

    @ResponseBody
    @RequestMapping(value = "/getMemberByPhone", method = RequestMethod.GET)
    public Object getMemberByPhone(String phone) {
        try {
            List<UmsMember> members = memberService.getMemberByPhone(phone);
            return new CommonResult().success(members);
        } catch (Exception be) {
            return new CommonResult().failed();
        }
    }

}
